<html>
<head><meta charset="utf-8"><title>Stacked Borrows and inter-process memory sharing · t-lang · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/index.html">t-lang</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html">Stacked Borrows and inter-process memory sharing</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="233361846"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233361846" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Pointerbender <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233361846">(Apr 06 2021 at 17:56)</a>:</h4>
<p>Might anyone know if there exist any publications about Stacked Borrows in the context of inter-process memory sharing? One example of this might be two processes that share the same memory through a memory mapped file. If these processes each independently obtained a mutable raw pointer to the memory mapped region, this might not be seen as a "re-tag" of the same pointer under the Stacked Borrows model. I tried to search the internet, but could not find anything related to it. Might it be that Stacked Borrows has not reached this far yet? Are there any ongoing initiatives at the moment that I could potentially read up on? :-)</p>



<a name="233394591"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233394591" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233394591">(Apr 06 2021 at 21:34)</a>:</h4>
<p>I would guess it would be equivalent to sharing between two threads in a single process.</p>



<a name="233434815"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233434815" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Pointerbender <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233434815">(Apr 07 2021 at 05:45)</a>:</h4>
<p>Hmm that is indeed a good way to look at it, but then you could run into some subtleties when each process has a raw pointer to the same memory mapped region (most likely obtained through FFI when making calls to mmap/libc/kernel), and I wonder how the Stacked Borrows model views this (or if this has been considered at all). From what I can gather, Stacked Borrows can only reason about what happens inside Rust and has a hard time looking past the FFI boundaries, hence it might still be "undefined" under the Stacked Borrows model if multiple processes have aliasing raw pointers that are not known to be "reborrowed" from the same origin. If it's the same process with multiple threads, at least we have the possibility to legally share the same pointer between the same threads.</p>



<a name="233440735"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233440735" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Pointerbender <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233440735">(Apr 07 2021 at 07:01)</a>:</h4>
<p>To expand a bit more on this: from what I can gather, when making calls to <code>mmap</code> with identical arguments on Linux, it will return identical raw pointers to each process (background discussion about this on reddit here: <a href="https://www.reddit.com/r/rust/comments/mjsezp/deferred_reference_compiletime_checked_reference/gtm17n6/?utm_source=share&amp;utm_medium=web2x&amp;context=3">https://www.reddit.com/r/rust/comments/mjsezp/deferred_reference_compiletime_checked_reference/gtm17n6/?utm_source=share&amp;utm_medium=web2x&amp;context=3</a> ), these raw pointers are actually a reborrow of the original pointer which is owned by the Linux kernel. However, since the kernel is compiled separately from the Rust binary, these raw pointers most likely don't share the same pointer provenance (relevant blog post from <span class="user-mention" data-user-id="120791">@RalfJ</span> on this topic: <a href="https://www.ralfj.de/blog/2020/12/14/provenance.html">https://www.ralfj.de/blog/2020/12/14/provenance.html</a> ). I guess this boils down to what does the Rust compiler do in this case? Since it can't infer pointer provenance, will it allow for pointer provenance optimizations that might lead to UB? Or perhaps it was accounted for in the Stacked Borrows model that when it sees raw pointers coming in through the FFI boundary, it applies certain LLVM flags to the pointer that would prevent this illegal optimizations from being introduced by the compiler? I'm having trouble reasoning about what the Stacked Borrows model says in this case, and it might very well be that this is still "undefined" at the moment :-) Hence I was curious if there exists any prior or ongoing work in this area.</p>



<a name="233470797"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233470797" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233470797">(Apr 07 2021 at 11:27)</a>:</h4>
<p><span class="user-mention" data-user-id="400735">@Pointerbender</span> This depends on how the <code>mmap</code> function's postcondition is expressed. It's an unsafe function so it's allowed to have additional requirements for safety, and the invariants depend on what the linux kernel provides and what the shim author supports. The compiler doesn't know what the invariants of an FFI function are, so it is required to assume the worst: the memory is arbitrary memory with wildcard provenance. When we dereference pointers into the memory we are implicitly asserting that the memory is valid, but the compiler has no idea where this valid memory came from so it can't soundly apply any provenance based optimizations.</p>



<a name="233491300"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233491300" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Pointerbender <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233491300">(Apr 07 2021 at 13:54)</a>:</h4>
<p>I see. The only (unofficial and outdated) source I could find around the <code>mmap</code> function's postcondition has this to say: <code>this-&gt;get_address() != 0 &amp;&amp; this-&gt;get_size() != 0 &amp;&amp; this-&gt;get_offset() == offset</code> (from <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2044.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2044.html</a> ). Inside the Linux kernel, there is also this bit: <a href="https://github.com/torvalds/linux/blob/master/mm/mmap.c#L1112-L1155">https://github.com/torvalds/linux/blob/master/mm/mmap.c#L1112-L1155</a> . At first glance, it matches with Rust's rules that say that pointers and pointers derived from pointers have to be part of the same "allocation region" and that it's not legal to dereference null-pointers (also pointers returned by <code>mmap</code> are page aligned).  Good to know that the compiler won't apply provenance optimizations on pointers obtained through FFI :) How could this fit into the Stacked Borrows model? If I understood the correctly, the raw (mutable) pointer becomes Untagged/SharedReadWrite as soon as it crosses the FFI boundary from libc into Rust territory. Does this mean that Stacked Borrows doesn't validate it? Even with the <code>-Zmiri-track-raw-pointers</code> flag passed to Miri? Or, will Miri start validating it as soon as the raw pointer is re-borrowed as a reference? (Let's assume that there exists a mechanism that upholds the Rust aliasing rules even amongst processes sharing the same memory, for the sake of simplicity :) ) Do raw pointers from FFI fall outside of the Stacked Borrows model, even if the invariants for these raw pointers are upheld?</p>



<a name="233538868"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233538868" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233538868">(Apr 07 2021 at 18:28)</a>:</h4>
<p>actually you <em>can</em> <code>mmap</code> to address <code>0</code> if you use <code>MAP_FIXED</code>, the actual post-condition is that the returned pointer is aligned to a page and not equal to  <code>MAP_FAILED</code> (<code>-1usize as *mut c_void</code>) unless <code>mmap</code> had an error.<br>
<a href="https://manpages.debian.org/stable/manpages-dev/mmap.2.en.html">https://manpages.debian.org/stable/manpages-dev/mmap.2.en.html</a></p>



<a name="233539208"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233539208" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233539208">(Apr 07 2021 at 18:30)</a>:</h4>
<p>mapping page <code>0</code> makes it legal to dereference a null pointer at the cpu level, that's still UB at the compiler level without taking special steps (using a different LLVM pointer address space)</p>



<a name="233547003"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233547003" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233547003">(Apr 07 2021 at 19:25)</a>:</h4>
<p>Mapping page 0 only works under special conditions with Linux.</p>



<a name="233938243"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233938243" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233938243">(Apr 10 2021 at 08:29)</a>:</h4>
<blockquote>
<p>Might anyone know if there exist any publications about Stacked Borrows in the context of inter-process memory sharing?</p>
</blockquote>
<p>There definitely is no such publication.^^</p>



<a name="233938254"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233938254" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233938254">(Apr 10 2021 at 08:29)</a>:</h4>
<p>I can't really think of any model of Inter-process memory sharing, let alone one accounting for pointer provenance (any kind of provenance, even just C-style)</p>



<a name="233938361"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233938361" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233938361">(Apr 10 2021 at 08:31)</a>:</h4>
<p>but I think if you treat <code>mmap</code> as a strange kind of <code>malloc</code>, and multiple processes sharing memory as similar to multiple threads acting on the same heap allocation, you should be on the safe side</p>



<a name="233942983"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233942983" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Pointerbender <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233942983">(Apr 10 2021 at 09:59)</a>:</h4>
<p>Thanks <span class="user-mention" data-user-id="120791">@RalfJ</span> ! Could <code>mmap</code> technically speaking be sound under the Stacked Borrows model if multiple processes obtain a <code>*mut</code> pointer to the same memory? I guess these pointers are not seen by Stacked Borrows as a reborrow, which would make this approach illegal under the current model? Or does the model not extend to outside of the current process, and would it be more accurate to say that this is currently "undefined" under the Stacked Borrows model? Or, is this legal after all when the <code>*mut</code> pointer first enters the "stack" of a process' memory model as Untagged/SharedReadWrite (even though Stacked Borrows can not reason about it then amongst distinct processes, and I guess the burden of proof then falls on the programmer)?</p>



<a name="233943741"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233943741" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233943741">(Apr 10 2021 at 10:12)</a>:</h4>
<p>aliasing <code>*mut</code> is fine, so I do not see the problem here. what are you concerned about?</p>



<a name="233943971"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233943971" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233943971">(Apr 10 2021 at 10:16)</a>:</h4>
<p>the way I view it, the two <code>mmap</code> in the two processes return aliasable pointers to the "new allocation" that <code>mmap</code> creates. unlike with <code>malloc</code>, those pointers can <em>not</em> assumed to be fresh in the sense that nobody else has access to them -- basically, the "initial stack" may contain not just the raw pointer returned but also some other raw pointers.</p>



<a name="233944749"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233944749" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Pointerbender <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233944749">(Apr 10 2021 at 10:31)</a>:</h4>
<blockquote>
<p>what are you concerned about?</p>
</blockquote>
<p>I just realized I have not been complete in my explanation :-) Where I was going with this in my thoughts is this: if I want to create a temporary mutable reference to (part of) the shared memory at some point in one of the processes (assuming this mutable reference is also exclusive amongst processes), wouldn't this invalidate the existing <code>*mut</code> pointers from the other processes, if these other <code>*mut</code> pointers are not reborrows? As long as no mutable references are created, it is fine to have aliasing <code>*mut</code>, but then a temporary mutable reference at some point could complicate things a bit more.</p>



<a name="233945094"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233945094" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233945094">(Apr 10 2021 at 10:36)</a>:</h4>
<p>yes, mutable references certainly make it more complicated. but I think it is reasonable to say that all the ptrs returned by <code>mmap</code> are "at the root", so to speak. which means that when you create a mutable reference from one of them, that does not invalidate the others.</p>



<a name="233945111"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233945111" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233945111">(Apr 10 2021 at 10:37)</a>:</h4>
<p>however, of course, if you use <em>any</em> of those raw pointers to read or write some memory, then all mutable references will be invalidated for that memory</p>



<a name="233949075"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stacked%20Borrows%20and%20inter-process%20memory%20sharing/near/233949075" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Pointerbender <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stacked.20Borrows.20and.20inter-process.20memory.20sharing.html#233949075">(Apr 10 2021 at 11:49)</a>:</h4>
<p>Nice! This insight opens up a whole new array of use cases for me, thanks! <span aria-label="smile" class="emoji emoji-1f642" role="img" title="smile">:smile:</span></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>